﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Web.Mvc;
using Diploma.Models;
using DiplomaWeb.Models;
using DiplomaWeb.Models.ConsultantOfPart;
using DiplomaWeb.Models.OrderDiplom;
using MvcPaging;
using OfficeOpenXml;
using OfficeOpenXml.Style;
using System.Web;

namespace DiplomaWeb.Controllers
{
    [Authorize(Roles = "SystemManager")]
    public class OrderDiplomController : MasterController
    {
        private int PageSize = 20;

        public OrderDiplomController(DataManager dataManager) : base(dataManager)
        {
        }

        #region Management OrderDiplom

        public ActionResult Home(int? page, int? pageSize)
        {
            var viewModel = new OrderDiplomViewModel
                                {
                                    Orders =
                                        DataManager.OrderDiplomRepository.GetAll().ToArray().ToPagedList(
                                            page.HasValue ? page.Value : 1,
                                            pageSize.HasValue ? pageSize.Value : PageSize),
                                    Search = new SearchOrderDiplomModel()
                                };

            return View("~/Views/SystemManagers/OrderDiplom/Orders.aspx", viewModel);
        }

        /// <summary>
        /// Работа с приказом
        /// </summary>
        /// <param name="orderId">Приказ</param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult Room(Guid orderId)
        {
            OrderDiplom model = DataManager.OrderDiplomRepository.GetOrder(orderId);
            ViewData.Model = model;
            return View("~/Views/SystemManagers/OrderDiplom/OrderRoom.aspx");
        }

        /// <summary>
        /// Создание приказа на диплом по приказу на практику
        /// </summary>
        /// <param name="subPracticeOrderId"></param>
        /// <returns></returns>
        [HttpGet]
        public ActionResult Create(Guid subPracticeOrderId)
        {
            SubOrderPractice subOrderModel = DataManager.SubOrderPracticeRepository.Get(subPracticeOrderId);
            const string textTemplate = "У відповідності до навчального плану нижчевказаних студентів 5-го курсу денної форми навчання, факультету <скорочена назва факультету> спеціальності <повна назва спеціальності>, направити з <дата у форматі ДД.ММ.РР> по <дата у форматі ДД.ММ.РР> на дипломування, закріпити за ними теми дипломних проектів, призначити керівників проектів та консультантів";
            const string dateAndOrderNumber = "_____________________№_______________________";
            var model = new OrderDiplom
                            {
                                Id = Guid.NewGuid(),
                                CreateDate = DateTime.Now,
                                UpdateDate = DateTime.Now,
                                OrderStatu = DataManager.OrderStatusRepository.GetStatus(0),
                                BookName = subOrderModel.BookName,
                                Title = String.Empty,
                                Text = textTemplate,
                                DateAndOrderNumber = dateAndOrderNumber
                            };
            int num = 1;
            foreach (SaveStateOrderPractice s in subOrderModel.SaveStateOrderPractices)
            {
                var student = new SaveStateOrderDiplom
                                  {
                                      Id = Guid.NewGuid(),
                                      Num = num,
                                      Fio = s.Fio,
                                      StudentGroup = s.StudentGroup,
                                      Lecturer = s.LecturerDiplom,
                                      Consultant = s.Counsultant,
                                      Theme = s.Theme,
                                      Note = s.Note
                                  };

                model.SaveStateOrderDiploms.Add(student);
                num++;
            }

            subOrderModel.OrderDiploms.Add(model);
            DataManager.SubOrderPracticeRepository.SaveChanges();

            return RedirectToRoute("Default", new
                                                  {
                                                      controller = "OrderDiplom",
                                                      action = "Room",
                                                      orderId = model.Id
                                                  });
        }

        #endregion

        /// <summary>
        /// Загрузка списка студентов
        /// </summary>
        /// <param name="orderId">Приказ</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult StudentList(Guid orderId)
        {
            OrderDiplom order = DataManager.OrderDiplomRepository.GetOrder(orderId);
            ViewData.Model = order;
            return View("~/Views/SystemManagers/OrderDiplom/StudentList.ascx");
        }

        /// <summary>
        /// Загрузка информиции о под приказе
        /// </summary>
        /// <param name="orderId">Приказ</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult GetInfo(Guid orderId)
        {
            OrderDiplom order = DataManager.OrderDiplomRepository.GetOrder(orderId);
            ViewData.Model = order;
            return View("~/Views/SystemManagers/OrderDiplom/OrderInfo.cshtml");
        }

        /// <summary>
        /// Форма редактирования информации
        /// </summary>
        /// <param name="orderId">Приказ</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult GetEditForm(Guid orderId)
        {
            OrderDiplom order = DataManager.OrderDiplomRepository.GetOrder(orderId);
            ViewData.Model = order;
            return View("~/Views/SystemManagers/OrderDiplom/EditOrderInfo.cshtml");
        }

        /// <summary>
        /// Сохранение информации
        /// </summary>
        /// <param name="orderId">Под приказ</param>
        /// <param name="title">Заголовок</param>
        /// <param name="text">Текст</param>
        /// <param name="bookName">Название книги</param>
        /// <param name="startDate">Начало практики</param>
        /// <param name="endDate">Окончание практики</param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult SaveInfo(Guid orderId, string title, string text, string bookName, string dateAndOrderNumber)
        {
            try
            {
                OrderDiplom model = DataManager.OrderDiplomRepository.GetOrder(orderId);

                model.Title = title;
                model.Text = text;
                model.BookName = bookName;
                model.DateAndOrderNumber = dateAndOrderNumber;

                DataManager.OrderDiplomRepository.SaveChanges();

                return Json(true);
            }
            catch (Exception)
            {
                return Json(false);
            }
        }


        /// <summary>
        /// Получение отображения статуса
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult GetStatus(Guid orderId)
        {
            OrderDiplom currentStatus = DataManager.OrderDiplomRepository.GetOrder(orderId);
            IEnumerable<OrderStatu> statuses = DataManager.OrderStatusRepository.GetAll();
            IEnumerable<SelectListItem> model;
            if (currentStatus.OrderStatu.Value == 0)
            {
                model = from b in statuses
                        where b.Value >= currentStatus.OrderStatu.Value
                        orderby b.Value
                        select new SelectListItem
                                   {
                                       Text = b.DisplayName,
                                       Value = b.Id.ToString(),
                                       Selected = b.Id == currentStatus.OrderStatu.Id
                                   };
            }
            else
            {
                model = from b in statuses
                        where b.Value >= currentStatus.OrderStatu.Value
                        where b.Value != 3
                        orderby b.Value
                        select new SelectListItem
                                   {
                                       Text = b.DisplayName,
                                       Value = b.Id.ToString(),
                                       Selected = b.Id == currentStatus.OrderStatu.Id
                                   };
            }
            ViewData.Model = model;
            return View("~/Views/SystemManagers/OrderDiplom/OrderStatus.ascx");
        }

        /// <summary>
        /// Сохранение статуса приказа
        /// </summary>
        /// <param name="orderId">Приказ</param>
        /// <param name="statusId">Статус</param>
        /// <returns></returns>
        [HttpPost]
        public JsonResult SaveStatus(Guid orderId, Guid statusId)
        {
            OrderDiplom order = DataManager.OrderDiplomRepository.GetOrder(orderId);
            OrderStatu status = DataManager.OrderStatusRepository.GetStatus(statusId);
            order.OrderStatu = status;
            DataManager.OrderDiplomRepository.SaveChanges();
            return Json(true);
        }

        [HttpPost]
        public ActionResult LoadExcelView(Guid orderId)
        {
            OrderDiplom order = DataManager.OrderDiplomRepository.GetOrder(orderId);
            ViewData.Model = order;
            return View("~/Views/SystemManagers/OrderDiplom/ExcelView.ascx");
        }

        /// <summary>
        /// Отображение формы загрузки
        /// </summary>
        /// <param name="orderId"></param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult UploadFilesView(Guid orderId)
        {
            OrderDiplom model = DataManager.OrderDiplomRepository.GetOrder(orderId);
            ViewData.Model = model;
            return View("~/Views/SystemManagers/OrderDiplom/UploadFiles.ascx");
        }

        /// <summary>
        /// Загрузка и прикрипление файла к приказу
        /// </summary>
        /// <param name="orderId">Приказ</param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult UploadFile(Guid orderId)
        {
            for (int i = 0; i < Request.Files.Count; i++)
            {
                if (Request.Files[i] != null)
                {
                    HttpPostedFileBase file = Request.Files[i];
                    //Проверка на размер файла
                    if (file != null && file.ContentLength > 0)
                    {
                        var fileName = String.Format("{0}_{1}", DateTime.Now.Ticks, file.FileName);
                        var path = String.Format("{0}{1}", Configuration.Settings.OrderDiplimContentPath, fileName);

                        if (!Directory.Exists(Configuration.Settings.OrderDiplimContentPath))
                        {
                            Directory.CreateDirectory(Configuration.Settings.OrderDiplimContentPath);
                        }

                        OrderDiplom order = DataManager.OrderDiplomRepository.GetOrder(orderId);
                        var document = new VerifyDocument
                        {
                            Id = Guid.NewGuid(),
                            DocumentURL = path
                        };
                        order.VerifyDocuments.Add(document);

                        file.SaveAs(path);
                        DataManager.OrderDiplomRepository.SaveChanges();
                    }
                }
            }
            return RedirectToRoute("Default", new {controller = "OrderDiplom", action = "Room", orderId});
        }

        [HttpPost]
        public ActionResult Content(Guid orderId, Guid documentId, string action)
        {
            OrderDiplom order = DataManager.OrderDiplomRepository.GetOrder(orderId);
            VerifyDocument file = order.VerifyDocuments.First(r => r.Id == documentId);
            var fileInfo = new FileInfo(file.DocumentURL);
            switch (action)
            {
                case "delete":
                    order.VerifyDocuments.Remove(file);
                    DataManager.OrderDiplomRepository.SaveChanges();
                    if (fileInfo.Exists)
                    {
                        fileInfo.Delete();
                    }
                    break;
                case "download":
                    if (fileInfo.Exists)
                    {
                        return File(fileInfo.FullName, "image/jpeg", fileInfo.Name);
                    }
                    break;
                default:
                    throw new Exception();
            }
            return RedirectToRoute("Default",
                                   new { controller = "OrderDiplom", action = "Room", orderId });
        }

        #region Excel

        /// <summary>
        /// Создание Excel файла
        /// </summary>
        /// <param name="orderId"></param>
        /// <param name="type"> </param>
        /// <returns></returns>
        [HttpPost]
        public ActionResult GenerateExcel(Guid orderId)
        {
            string path = Configuration.Settings.OrderDiplimPath + orderId + ".xls";
            var fileInfo = new FileInfo(path);
            if (fileInfo.Directory != null && !fileInfo.Directory.Exists)
            {
                Directory.CreateDirectory(fileInfo.Directory.FullName);
            }
            OrderDiplom order = DataManager.OrderDiplomRepository.GetOrder(orderId);

            Template(fileInfo, order);

            var title = !String.IsNullOrWhiteSpace(order.Title) ? order.Title : "Default";

            return base.File(fileInfo.FullName, "application/ms-excel", title + ".xls");
        }

        #endregion

        #region Private
        
        private static void Template(FileInfo fileInfo, OrderDiplom order)
        {
            using (var p = new ExcelPackage())
            {
                ExcelWorksheet ws = p.Workbook.Worksheets.Add(order.BookName);
                int rowId = 11;
                int i = 0;

                ws.Column(1).Width = 5.0; // A
                ws.Column(2).Width = 35.86; // B
                ws.Column(3).Width = 12; // C
                ws.Column(4).Width = 29.29; // D
                ws.Column(5).Width = 53.14; // E
                ws.Column(6).Width = 43.71; // 
                ws.Column(7).Width = 28.71; // F
                ws.Column(8).Width = 12.29; // G

                ws.Row(1).Height = 30;
                ws.Row(2).Height = 25.5;
                ws.Row(3).Height = 26.25;
                ws.Row(4).Height = 26.25;
                ws.Row(5).Height = 23.25;
                ws.Row(6).Height = 20.25;
                ws.Row(7).Height = 31.5;
                ws.Row(8).Height = 80.25;

                ws.Row(9).Height = 9.75;
                ws.Row(10).Height = 13.5;
                ws.Row(11).Height = 30.75;
                ws.Row(12).Height = 36;

                ws.Cells["A1:G1000"].Style.Font.Name = "Times New Roman";

                ws.Cells["A1:G1000"].Style.Font.Size = 16;
                ws.Cells["D2,D3,D4"].Style.Font.Size = 20;

                //Текст жирным
                ws.Cells["D1,D2,D3,D4"].Style.Font.Bold = true;
                //Перенос текста
                ws.Cells["A8,A11,B11,C11,D11,E11,F11,G11,H11,J11"].Style.WrapText = true;

                //Вертикальное выравнивание
                ws.Cells["A8"].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["A6"].Style.VerticalAlignment = ExcelVerticalAlignment.Bottom;

                //Горизонтальное выравнивание
                ws.Cells["D1,D2,D3,D4"].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;


                ws.Cells["D1:F1"].Merge = true;
                ws.Cells["D1"].Value = "Міністерство освіти і науки України";

                ws.Cells["D2:F2"].Merge = true;
                ws.Cells["D2"].Value = "ХАРКIВСЬКИЙ НАЦІОНАЛЬНИЙ";

                ws.Cells["D3:F3"].Merge = true;
                ws.Cells["D3"].Value = "УНIВЕРСИТЕТ РАДIОЕЛЕКТРОНIКИ";

                ws.Cells["D4:F4"].Merge = true;
                ws.Cells["D4"].Value = "НАКАЗ";

                ws.Cells["A5:D5"].Merge = true;
                //ws.Cells["A5"].Value = "_____________________№_______________________";
                ws.Cells["A5"].Value = order.DateAndOrderNumber;
                
                ws.Cells["A6:D6"].Merge = true;
                ws.Cells["A6"].Value = "Про направлення на дипломування";

                ws.Cells["A8:G8"].Merge = true;
                ws.Cells["A8"].Value = "1. " + order.Text;

                //Заполнение тела приказа с студентами

                ws.Cells["A11:A12"].Merge = true;
                ws.Cells["A11"].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["A11"].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                ws.Cells["A11"].Value = "№ п/п";

                ws.Cells["B11:B12"].Merge = true;
                ws.Cells["B11"].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["B11"].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                ws.Cells["B11"].Value = "Прізвище, ім'я та по батькові студента";

                ws.Cells["C11:C12"].Merge = true;
                ws.Cells["C11"].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["C11"].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                ws.Cells["C11"].Value = "Учбова група";

                ws.Cells["D11:D12"].Merge = true;
                ws.Cells["D11"].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["D11"].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                ws.Cells["D11"].Value = "Керівник дипломного проекту";

                ws.Cells["E11:E12"].Merge = true;
                ws.Cells["E11"].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["E11"].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                ws.Cells["E11"].Value = "Тема дипломного проекту";

                ws.Cells["F11:F12"].Merge = true;
                ws.Cells["F11"].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["F11"].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                ws.Cells["F11"].Value = "Консультант зі спецчастини";

                ws.Cells["G11:G12"].Merge = true;
                ws.Cells["G11"].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["G11"].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                ws.Cells["G11"].Value = "Примітки";
                
                if (order.SaveStateOrderDiploms == null)
                    return;

                foreach (SaveStateOrderDiplom item in order.SaveStateOrderDiploms)
                {
                    rowId++;
                    i++;

                    ws.Cells["A" + rowId].Value = i;
                    ws.Cells["B" + rowId].Value = item.Fio;
                    ws.Cells["C" + rowId].Value = item.StudentGroup;
                    ws.Cells["D" + rowId].Value = item.Lecturer;
                    ws.Cells["E" + rowId].Value = item.Theme;
                    ws.Cells["F" + rowId].Value = item.Consultant;
                    ws.Cells["G" + rowId].Value = item.Note;
                }
                ws.Cells["A13:A" + rowId].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["B13:B" + rowId].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["C13:C" + rowId].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["D13:D" + rowId].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["E13:E" + rowId].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["F13:F" + rowId].Style.VerticalAlignment = ExcelVerticalAlignment.Center;
                ws.Cells["G13:G" + rowId].Style.VerticalAlignment = ExcelVerticalAlignment.Center;

                ws.Cells["B13:B" + rowId].Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
                ws.Cells["C13:C" + rowId].Style.HorizontalAlignment = ExcelHorizontalAlignment.Center;
                ws.Cells["D13:D" + rowId].Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
                ws.Cells["E13:E" + rowId].Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
                ws.Cells["F13:F" + rowId].Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
                ws.Cells["G13:G" + rowId].Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;


                ws.Cells["A13:A" + rowId].Style.WrapText = true;
                ws.Cells["B13:B" + rowId].Style.WrapText = true;
                ws.Cells["C13:C" + rowId].Style.WrapText = true;
                ws.Cells["D13:D" + rowId].Style.WrapText = true;
                ws.Cells["E13:E" + rowId].Style.WrapText = true;
                ws.Cells["F13:F" + rowId].Style.WrapText = true;
                ws.Cells["G13:G" + rowId].Style.WrapText = true;

                ws.Cells["A11:G" + rowId].Style.Border.Top.Style = ExcelBorderStyle.Thin;
                ws.Cells["A11:G" + rowId].Style.Border.Bottom.Style = ExcelBorderStyle.Thin;
                ws.Cells["A11:G" + rowId].Style.Border.Right.Style = ExcelBorderStyle.Thin;
                ws.Cells["A11:G" + rowId].Style.Border.Left.Style = ExcelBorderStyle.Thin;
                
                //Описание нижней части приказа
                //_______//
                rowId = rowId + 2;

                int index = 2;
                foreach (var consultantOfPart in order.ConsultantOfParts)
                {
                    ws.Cells["A" + rowId].Value = String.Format("{0}.", index);
                    ws.Cells["B" + rowId + ":F" + rowId].Merge = true;
                    ws.Cells["B" + rowId].Value = consultantOfPart.Text;
                    index++;
                    rowId++;
                }

                //_______//
                rowId = rowId + 2;

                ws.Cells["A" + rowId + ":C" + rowId].Merge = true;
                ws.Cells["A" + rowId].Value = "Перший проректор";
                ws.Cells["A" + rowId].Style.HorizontalAlignment = ExcelHorizontalAlignment.Left;
                ws.Cells["A" + rowId].Style.VerticalAlignment = ExcelVerticalAlignment.Center;

                ws.Cells["E" + rowId].Value = "В.В. Семенець";
                ws.Cells["E" + rowId].Style.HorizontalAlignment = ExcelHorizontalAlignment.Right;
                ws.Cells["E" + rowId].Style.VerticalAlignment = ExcelVerticalAlignment.Bottom;

                //_______//
                rowId++;
                ws.Row(rowId).Height = 17.25;

                //_______//
                rowId++;
                ws.Row(rowId).Height = 8.25;

                //_______//
                rowId++;
                ws.Cells["A" + rowId + ":B" + rowId].Merge = true;
                ws.Cells["A" + rowId].Value = "Проект наказу вносить:";

                ws.Cells["E" + rowId].Value = "Узгоджено:";
                ws.Cells["E" + rowId].Style.WrapText = true;

                //_______//
                rowId++;
                ws.Cells["A" + rowId + ":B" + rowId].Merge = true;
                ws.Cells["A" + rowId].Value = "В.о.зав. кафедри ПЗ ЕОМ";

                ws.Cells["E" + rowId].Value = "Декан ф-ту";

                //_______//
                rowId++;
                ws.Cells["C" + rowId].Value = "З.В.Дудар";
                ws.Cells["F" + rowId].Value = "В.П.Машталір";

                //_______//
                rowId++;
                ws.Cells["E" + rowId].Value = "Начальник ВОНП";

                //_______//
                rowId++;
                ws.Cells["F" + rowId].Value = "В.В. Логвін";
                
                p.SaveAs(fileInfo);
            }
        }

        #endregion
        
        [HttpGet]
        public ActionResult ConsultantForOrderList(Guid orderId)
        {
            var viewModel = new ConsultantsForOrderViewModel();
            var order = DataManager.OrderDiplomRepository.GetOrder(orderId);
            var source = DataManager.ConsultantOfPartRepository.GetAll();
            viewModel.ToViewModel(source, order, orderId);

            return View(viewModel);
        }

        [HttpPost]
        public ActionResult AddConsultantForOrder(Guid orderId, Guid consultantId)
        {
            DataManager.OrderDiplomRepository.AttachConsultant(orderId, consultantId);
            return RedirectToRoute("Default", new { controller = "OrderDiplom", action = "Room", orderId });
        }

        [HttpGet]
        public ActionResult RemoveConsultantForOrder(Guid orderId, Guid consultantId)
        {
            DataManager.OrderDiplomRepository.DettachConsultant(orderId, consultantId);
            return RedirectToRoute("Default", new { controller = "OrderDiplom", action = "Room", orderId });
        }
    }
}